package com.loancalculator;

public class Caculator {
	public static Loan eqLoanCalculate(double balance, int months,double rate) {
		double baseAmount = 0, totalAmount = 0, totalInterest = 0;
		double monthRate0 = Double.MIN_VALUE, monthAmount = Double.MIN_VALUE;
		for (int month = months; month >= 1; month--) {
			double monthRate = GetMonthRate(months, rate);
			
			double interest = roundDouble(balance * monthRate,2);
			
//			System.out.println("balance:" + balance + "monthRate:" + monthRate + "interest:" + interest);
			if (monthRate0 != monthRate)
				monthAmount = GetMonthAmount(balance, monthRate0 = monthRate,
						month);
			baseAmount = monthAmount - interest;
			balance -= baseAmount;
			if (month == 1 && balance != 0) {
				baseAmount += balance;
				interest -= balance;
				balance = 0;
			}
			totalAmount += monthAmount;
			totalInterest += interest;
//			System.out.println(totalAmount + " " + totalInterest);
		}
		Loan loan = new Loan();
		loan.setMonthAmount(monthAmount);
		loan.setTotalAmount(totalAmount);
		loan.setTotalInterest(totalInterest);
		return loan;
	}

	public static Loan DescCalculate(double balance, int months,double rate)
    {
		double baseAmount = roundDouble(balance / months,2), totalAmount = 0, totalInterest = 0;
      for (int month = months; month >= 1; month--)
      {
    	  double monthRate = GetMonthRate( months, 6.55);
    	  double interest = roundDouble(balance * monthRate,2);
    	  double monthAmount = baseAmount + interest;
        balance -= baseAmount;
        if (month == 1 && balance != 0)
        {
          baseAmount += balance;
          monthAmount += balance;
          balance = 0;
        }
        totalAmount += monthAmount;
        totalInterest += interest;
        //Table.Rows.Add(new object[] { monthAmount, totalAmount, totalInterest });
        
      }
		Loan loan = new Loan();
//		loan.setMonthAmount(monthAmount);
		loan.setTotalAmount(totalAmount);
		loan.setTotalInterest(totalInterest);
		return loan;
    }
	
	static double GetMonthAmount(double balance, double monthRate, int months) {

		double tmp = pow(1 + (double) monthRate, months);
		System.out.println(tmp);
		return (double) ((double) balance * (double) monthRate * tmp / (tmp - 1));
	}

	public static double roundDouble(double val, int precision) {
		double ret = 0;
		try {
		double factor = pow(10, precision);
		ret = Math.floor(val * factor + 0.5) / factor;
		} catch (Exception e) {
		e.printStackTrace();
		}

		return ret;
		}
	
	static double pow(double x, double y) {
		int den = 1024;
		int num = (int)(y*den); 
		int iterations = 10;
		double n = Double.MAX_VALUE;
		while( n >= Double.MAX_VALUE && iterations > 1) { 
		n = x; 
		for( int i=1; i < num; i++ )n*=x; 
		if( n >= Double.MAX_VALUE ) {  
		iterations--;
		den = (int)(den / 2);
		num = (int)(y*den);
		}
		}
		for( int i = 0; i < iterations; i++ )
		{  
		n = Math.sqrt(n);  
		}  
		return n;
		} 

	static double GetMonthRate(int months, double rate) {
		return (double) (rate) / 100 / 12;
	}
	
	
}
